﻿
Imports std

Namespace internalFunctions
    'paramters, script, any, convert to string, script source
    '           app, pointer<var>, return app
    'return, bool, whether the parse is success or not
    Public Class runtimeparse
        Inherits internalFunction

        Public Class parameters
            Public Const script As String = "script"
            Public Const app As String = "app"
        End Class

        Private Shared m As iParametersMapping = Nothing

        Shared Sub New()
            initialMapping(m, parameters.script, parameters.app)
        End Sub

        Public Sub New()
            MyBase.New("elpmis.parse", m)
        End Sub

        Protected Overrides Function invoke(ByVal ctx As context, ByRef output As bare_variable) As Boolean
            Dim script As String = Nothing
            If Not ctx.findVariableStr(parameters.script, script) Then
                raiseError("expect parameter " + parameters.script, errorHandle.errorType.user)
                Return False
            Else
                Dim app As pointer(Of pointer(Of Object)) = Nothing
                If Not ctx.findVariable(parameters.app, app) Then
                    raiseError("expect parameter " + parameters.app + " is pointer<var>.", errorHandle.errorType.user)
                    Return False
                Else
                    Dim appInstance As app = Nothing
                    If elpmis.app.parse(script, appInstance) Then
                        app.instance().setinstance(appInstance)
                        output = New bare_variable(typeDefination.bool, True)
                    Else
                        output = New bare_variable(typeDefination.bool, False)
                    End If

                    Return True
                End If
            End If
        End Function
    End Class

    'parameters, app, var, app instance, returned by runtimeparse<elpmis.parse>
    '            startFunctionName
    '            p1, parameter 1
    '            p2, parameter 2
    '            ... pn, parameter n
    '            rtn, pointer<var>, return value of app
    'return, bool, whether the invoke is success or not
    Public Class runtimeinvoke
        Inherits internalFunction

        Public Class parameters
            Public Const app As String = "app"
            Public Const startFunctionName As String = "startFunctionName"
            Public Const pbase As String = "p"
            Public Const rtn As String = "rtn"
        End Class

        Private Shared m As iParametersMapping = Nothing

        Shared Sub New()
            initialMapping(m, parameters.app, parameters.startFunctionName, parameters.rtn)
        End Sub

        Public Sub New()
            MyBase.New("elpmis.invoke", m)
        End Sub

        Protected Overrides Function invoke(ByVal ctx As context, ByRef output As bare_variable) As Boolean
            Dim app As app = Nothing
            If Not ctx.findVariable(parameters.app, app) Then
                raiseError("expect parameter " + parameters.app + " is app.", errorHandle.errorType.user)
                Return False
            Else
                Dim startFunctionName As String = Nothing
                If Not ctx.findVariableStr(parameters.startFunctionName, startFunctionName) Then
                    raiseError("expect parameter " + parameters.startFunctionName, errorHandle.errorType.user)
                    Return False
                Else
                    Dim ps As parameters_t = Nothing
                    ps = New parameters_t()

                    Dim i As Int64
                    i = 1
                    Dim this As bare_variable = Nothing
                    While ctx.findVariable(parameters.pbase + Convert.ToString(i), this)
                        ps.push_back(make_pair(CType(Nothing, String), this))
                        i += 1
                    End While

                    Dim rtn As pointer(Of pointer(Of Object)) = Nothing
                    ctx.findVariable(parameters.rtn, rtn)

                    Dim rst As bare_variable = Nothing
                    If app.invoke(startFunctionName, ps, rst) Then
                        If Not rtn Is Nothing Then
                            rtn.instance().setinstance(rst)
                        End If

                        output = New bare_variable(typeDefination.bool, True)
                    Else
                        output = New bare_variable(typeDefination.bool, False)
                    End If
                    Return True
                End If
            End If
        End Function
    End Class

    'parameters, N/A
    'return, string, the call stack to current function
    Public Class _callstack
        Inherits internalFunction

        Public Class parameters
        End Class

        Private Shared a As aliases = Nothing

        Shared Sub New()
            initialAliases(a, "callstack")
        End Sub

        Public Sub New()
            MyBase.New("elpmis.callstack", a)
        End Sub

        Protected Overrides Function invoke(ByVal ctx As context, ByRef output As bare_variable) As Boolean
            output = New bare_variable(typeDefination.string, context.callstack())
            Return True
        End Function
    End Class

    Public Class elpmisinvoke
        Inherits name_parameters_t_ps_function(Of Object)

        Public Sub New()
            MyBase.New("reflection.invoke.byname")
        End Sub

        Protected Overrides Function returnType() As typeDefination
            Return typeDefination.var
        End Function

        Protected Overrides Function invoke(ByVal ctx As context, ByVal name As String, _
                                            ByVal ps As parameters_t, ByRef o As Object) As Boolean
            Dim rtn As bare_variable = Nothing
            If ctx.invoke(name, convertor.cast(Of iParametersWithMapping)(ps), rtn) Then
                If Not rtn Is Nothing Then
                    o = rtn.value()
                End If
                Return True
            Else
                Return False
            End If
        End Function
    End Class

    Public Class elpmisvar
        Inherits inputIFunction(Of String, Object)

        Public Sub New()
            MyBase.New("reflection.var.byname")
        End Sub

        Protected Overrides Function finder() As iVariableFinder(Of String)
            Return string_finder()
        End Function

        Protected Overrides Function invoke(ByVal i As String, ByRef o As Object) As Boolean
            Dim bv As bare_variable = Nothing
            If context.currentContext().findVariable(i, bv) Then
                o = bv.value()
                Return True
            Else
                raiseError(errorHandle.errorType.user, "no variable ", i, " found in current context")
                Return False
            End If
        End Function

        Protected Overrides Function returnType() As typeDefination
            Return typeDefination.var
        End Function
    End Class

    Public Class quit
        Inherits noInputFunction(Of Boolean)

        Public Sub New()
            MyBase.New("quit")
        End Sub

        Protected Overloads Overrides Function invoke(ByRef o As Boolean) As Boolean
            raiseError("force quit application.")
            Return False
        End Function

        Protected Overrides Function returnType() As typeDefination
            Return typeDefination.bool
        End Function
    End Class

    Public Class hasfunction
        Inherits inputIFunction(Of String, Boolean)

        Private Shared a As aliases = Nothing

        Shared Sub New()
            initialAliases(a, "runtime.isfunction", "runtime.hasfunc", "runtime.isfunc")
        End Sub

        Public Sub New()
            MyBase.New("runtime.hasfunction", a)
        End Sub

        Protected Overrides Function finder() As iVariableFinder(Of String)
            Return string_finder()
        End Function

        Protected Overrides Function invoke(ByVal i As String, ByRef o As Boolean) As Boolean
            o = context.currentContext().findFunction(i, Nothing)
            Return True
        End Function

        Protected Overrides Function returnType() As typeDefination
            Return typeDefination.bool
        End Function
    End Class

    Public Class hasvariable
        Inherits inputIFunction(Of String, Boolean)

        Private Shared a As aliases = Nothing

        Shared Sub New()
            initialAliases(a, "runtime.isvariable", "runtime.hasvar", "runtime.isvar")
        End Sub

        Public Sub New()
            MyBase.New("runtime.hasvariable", a)
        End Sub

        Protected Overrides Function finder() As iVariableFinder(Of String)
            Return string_finder()
        End Function

        Protected Overrides Function invoke(ByVal i As String, ByRef o As Boolean) As Boolean
            o = context.currentContext().parent().findVariable(i, Nothing)
            Return True
        End Function

        Protected Overrides Function returnType() As typeDefination
            Return typeDefination.bool
        End Function
    End Class

    Public Class _typeof
        Inherits inputIFunction(Of String, String)

        Public Sub New()
            MyBase.New("typeof")
        End Sub

        Protected Overrides Function finder() As iVariableFinder(Of String)
            Return string_finder()
        End Function

        Protected Overrides Function invoke(ByVal i As String, ByRef o As String) As Boolean
            Dim ctx As context = Nothing
            ctx = context.currentContext().parent()
            If ctx.findFunction(i, Nothing) Then
                o = "function"
            Else
                Dim bv As bare_variable = Nothing
                If ctx.findVariable(i, bv) Then
                    o = typeNaming(bv.variable().type())
                Else
                    o = "null"
                End If
            End If
            Return True
        End Function

        Protected Overrides Function returnType() As typeDefination
            Return typeDefination.string
        End Function
    End Class
End Namespace
